Skip to content

feat(core): add deepAssert evidence-chain assertions - #3099

Open
xzh6656 wants to merge 1 commit into
web-infra-dev:mainfrom
xzh6656:feat/deep-assert-evidence
Open

feat(core): add deepAssert evidence-chain assertions#3099
xzh6656 wants to merge 1 commit into
web-infra-dev:mainfrom
xzh6656:feat/deep-assert-evidence

Conversation

@xzh6656

@xzh6656 xzh6656 commented Sep 4, 2026

Copy link
Copy Markdown

概述

原先的 aiAssert 只根据最后一张截图判断断言是否成立。静态页面检查够用,但一旦断言依赖「刚刚发生过的动作」,这套证据就不对了:toast 已经消失、歌曲只在动作窗口里切过、提交后表单看起来没变、按钮状态只在 before-callingafter-calling 之间翻转。

本 PR 增加 deepAssert 证据链断言。默认开启,并兼容旧的三参 aiAssert(assertion, message, options)

deepAssert 做的事:

  • Action Space 任务录制 before-calling 和编号后的 after-calling-N(由 AfterActPicturesInterval 控制)。
  • 断言历史从当前 Agent dump 里取,用 AssertionContextBoundarylastAssert / session)、BeforeExecutionsBeforeTasks 划窗口。
  • 只把 Action Space 的证据图送给模型,去重后最新在前,数量不超过 MaxPictures
  • Planning / 最终规划摘要截图一律不当断言证据。
  • MaxPictures = 0 直接失败。没有历史图时回退当前截图,并标记 assertionEvidenceFallback: 'currentScreenshot'
  • 要求模型按四段中文作答:当前界面判断 / 关联 task 分析 / 截图证据分析 / 最终结论。关联 task 必须逐条精确引用。
  • 报告和回放把图片再反转成最旧在前,标签为 参考图N / name

{ deepAssert: false } 仍走原来的「只看最后一帧」行为。

要解决的问题

现在的断言是一次 Insight extract,只看最新 UIContext。实际会踩三个坑:

  1. 缺过程证据。 很多断言说的是变化(「下一首已切换」「toast 出现过」「表单已提交」)。等到断言时,最后一帧往往已经看不出变化。
  2. 图选错了。 最后一个 task 的快照可能来自 Planning 或非动作任务,那不是动作前后证据。
  3. 没有任务上下文。 模型看不到最近哪些 act / locate / assert 在范围内,只能对着一张图和一句提示词猜。

deepAssert 把断言改成对有边界的动作证据链做复核,而不是对单张截图做一次性问答。

实现路径

改动接到现有执行、dump、报告链路上,没有另起一套 runner。

aiAct 选项                      aiAssert 选项
 AfterActPictures / Interval     deepAssert / 边界 / 窗口 / MaxPictures
        |                                |
        v                                v
 TaskRunner.flush                   TaskExecutor.createTypeQueryExecution
  仅 Action Space:                  读取 Agent.dump.executions
  before-calling                     recentAssertionExecutions()
  after-calling-1..N                 buildEvaluationContext()
        |                            selectAssertionEvidenceImages()
        |                                |
        +------------ dump --------------+
                                         v
                            Insight extract(证据图最新在前)
                            composeAssertThought()
                                         v
                            报告 detail-panel + visualizer 回放
                            (展示最旧在前,参考图N)

1. 公开选项

  • AiActOptionsAfterActPictures(默认 1),Interval(默认 50 ms)。
  • AgentAssertOpt / InsightAPI.aiAssertdeepAssert(默认 true),AssertionContextBoundary(默认 'lastAssert'),BeforeExecutions(默认 1),BeforeTasks(默认 1),MaxPictures(默认 2)。
  • aiAssert 支持二参「断言 + 选项」,也兼容旧三参。
  • YAML / @midscene/test 工作流节点透传同样字段。

2. 录制动作证据

TaskRunner 只在 Action Space 任务上挂证据帧:

  • 执行动作前立刻拍 before-calling
  • 动作结束后拍 after-calling-1..N,帧之间隔 Interval

非动作任务的最后一个 task 仍用原来的单张 after-calling,Planning / Insight 的报告表现不变。

3. 为断言选历史

TaskExecutor 通过 getAssertionExecutions: () => this.dump.executions 拿到会话历史。

createTypeQueryExecution('Assert') 里:

  • lastAssert:只取上一次断言之后的 execution
  • session:取当前会话里最近的 execution
  • 跳过 Log 任务和最终 Planning 摘要
  • 保留连续的最近 BeforeTasks 个任务
  • 最多选 MaxPictures 张不重复的 Action Space 图,最新在前

4. 模型输入

AiExtractElementInfo 把具名证据图当作主要视觉输入。有证据图时不再附当前截图。上下文里写明断言目标、所选 execution、Task N 引用,以及图名。

没有历史图时回退当前截图,并写 assertionEvidenceFallback: 'currentScreenshot'

5. thought 与报告

composeAssertThought() 把模型回复整理成四段中文,并写入逐条 task 引用。报告 / 回放通过 buildDeepAssertScreenshots() / deepAssertEvidence()assertionEvidenceImages,展示时反转为最旧在前,标签 参考图N / name

默认值与关闭方式

选项 默认值
deepAssert true
AssertionContextBoundary 'lastAssert'
BeforeExecutions 1
BeforeTasks 1
MaxPictures 2
AfterActPictures 1
Interval 50
await agent.aiAct('点击提交按钮');
await agent.aiAssert('表单已提交成功');

await agent.aiAssert('表单已提交成功', {
  BeforeTasks: 2,
  MaxPictures: 4,
});

await agent.aiAssert('只看当前画面', { deepAssert: false });

改动文件

新增:packages/core/src/agent/assertion-evidence.ts 及单测。

只接到现有文件:types.tsagent.tsinsight.tstasks.tstask-runner.tsextraction.ts、report 截图栏、visualizer 回放、@midscene/test 选项 schema。

未包含:本地 Android testcases/、生成的 dump、快照换行噪音、二进制、dist

测试计划

  • packages/core 证据链单测(选项归一、历史窗口、最新图优先、MaxPictures = 0、当前截图回退、四段 thought)
  • task-runner 只在 Action Space 录 before-calling 和编号 after-calling-N
  • insight-extract-prompt 发送证据图且不带当前截图
  • tasks-null-data 在默认 deepAssert: true 下 Assert 路径仍可用
  • visualizer 回放 mock 补齐 deepAssertEvidence / buildDeepAssertScreenshots
  • 可选:真机 / 真实 VLM 端到端(aiActaiAssert,检查 HTML 报告截图栏)

Judge assertions from action before/after screenshots and recent task history instead of only the last frame.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant